<?php
// Исключаем прямой доступ
defined('_JEXEC') or die('Restricted access');

// Подключаем библиотеки
jimport('joomla.filesystem.file');
jimport('joomla.filesystem.folder');
jimport('joomla.filesystem.archive');
jimport('joomla.filesystem.archive.zip');

// Создаем класс парсера
class UpdaterOCS {

	// Объявляем переменные
	public $ok = true;
	public $alias = 'ocs'; // Алиас дистрибьютора
	public $title = 'OCS'; // Имя дистрибьютора

	protected $updater;
	protected $contractor;
	protected $stock = array();
	protected $priceType = array();

	protected $file;
	protected $data = array();
	protected $numbers = array();
	protected $product = array();

	protected $msg;

	// Точка входа
	public function update($id) {
	$this->addMsg("public function update($id)");

		// Получаем всю необходимую информацию о загрузчике
		if (true != $this->updater = $this->getUpdater($id)) { return false; }

		// Получаем всю необходимую информацию о контрагенте загрузчика
		if (true != $this->contractor = $this->getContractor()) { return false; }

		// Получаем идентификаторы складов контрагента
//		if (true != $this->stock['treolan-russia-stock'] = $this->getStock('treolan-russia-stock')) { return false; }
//		if (true != $this->stock['treolan-russia-transit'] = $this->getStock('treolan-russia-transit')) { return false; }

		// Получаем идентификаторы типов цен
//		if (true != $this->priceType['rdp'] = $this->getPriceType('rdp')) { return false; }

		// Загружаем прайс во временную папку
		if (true != $this->file = $this->getFile()) { return false; }

		// Загружаем данные в массив
//		if (true != $this->getData($this->file)) { return false; }

		// Идентифицируем колонки
//		if (true != $this->getNumbers()) { return false; }

		// Убираем устаревшие данные из базы
//		if (true != $this->clearSQL()) { return false; }

		// Загружаем данные в базу
//		if (true != $this->toSQL()) { return false; }
	}

	// Возвращает информацию о загрузчике (по id из базы)
	private function getUpdater($id) {
	$this->addMsg("private function getUpdater($id)");

		// Инициализируем переменные
		$db =& JFactory::getDBO();

		// Выполняем запрос
		$query = "SELECT * FROM `#__pricer_robot` WHERE `#__pricer_robot`.`id` = $id;";
		$db->setQuery($query);
		$updater = $db->loadObject();

		// Возвращаем результат
		return $updater;
	}

	// Возвращает информацию о контрагенте (по alias из базы), если его нет - добавляет
	private function getContractor() {
	$this->addMsg("private function getContractor()");
	

		// Инициализируем переменные и готовим запрос
		$db =& JFactory::getDBO();

		// Выполняем запрос
		$query = "SELECT * FROM `#__pricer_contractor` WHERE `alias` = '{$this->alias}';";
		$db->setQuery($query);
		$contractor = $db->loadObject();

		// Проверяем существование контрагента и его привязку к загрузчику
		if ((true == $contractor->id) and ($this->updater->contractor_id == $contractor->id)) {

			// Контрагент есть и привязан к загрузчику - возвращаем результат
			return $contractor;

		} elseif (true == $contractor->id) {// Контрагент есть, но не привязан к загрузчику

			// Привязываем контрагента к загрузчику
			$query = "UPDATE `#__pricer_robot` SET `contractor_id` = {$contractor->id} WHERE `id` = '{$this->updater->id}';";
			$db->setQuery($query);
			$db->query();

			// Возвразщаем результат
			return $contractor;

		} else { // Контрагента нет

			// Добавляем контрагента
			$this->addContractor();

			// Повторно выполняем запрос
			$query = "SELECT * FROM `#__pricer_contractor` WHERE `alias` = '{$this->alias}';";
			$db->setQuery($query);
			$contractor = $db->loadObject();

			// Привязываем контрагента к загрузчику
			$query = "UPDATE `#__pricer_robot` SET `contractor_id` = {$contractor->id} WHERE `id` = '{$this->updater->id}';";
			$db->setQuery($query);
			$db->query();

			// Возвращаем результат
			return $contractor; // Возможно, стоит перед возвращением результата выполнить повторную проверку
		}
	}

	// Создает контрагента
	private function addContractor() {
	$this->addMsg("private function addContractor()");

		// Инициализируем переменные и готовим запрос
		$db =& JFactory::getDBO();

		// Выполняем запрос
		$query = "
			INSERT INTO #__pricer_contractor (
				`id`,
				`title`,
				`alias`,
				`created`)
			VALUES (
				0,
				'{$this->title}',
				'{$this->alias}',
				NOW()
			);
		";
		$db->setQuery($query);
		$db->query();
	}

	// Возвращает id склада (по alias из базы), если его нет - добавляет
	private function getStock($alias) {
	$this->addMsg("private function getStock($alias)");

		// Инициализируем переменные и готовим запрос
		$db =& JFactory::getDBO();

		// Выполняем запрос
		$query = "SELECT * FROM `#__pricer_stock` WHERE `alias` = '{$alias}';";
		$db->setQuery($query);
		$stock = $db->loadObject();

		// Проверяем существование склада и его привязку к контрагенту
		if ((true == $stock->id) and ($this->stock->contractor_id == $contractor->id)) {

			// Склад есть и привязан к контрагенту - возвращаем результат
			return $stock->id;

		} elseif (true == $stock->id) { // Склад есть, но не привязан к контрагенту

			// Привязываем склад к контрагенту
			$query = "UPDATE `#__pricer_stock` SET `contractor_id` = {$contractor->id} WHERE `id` = '{$stock->id}';";
			$db->setQuery($query);
			$db->query();

			// Возвразщаем результат
			return $stock->id;

		} else { // Склада нет

			// Добавляем склад в базу
			$this->addStock($alias);

			// Повторно выполняем запрос
			$query = "SELECT * FROM `#__pricer_stock` WHERE `alias` = '{$alias}';";
			$db->setQuery($query);
			$stock = $db->loadObject();

			// Привязываем контрагента к загрузчику
			$query = "UPDATE `#__pricer_stock` SET `contractor_id` = {$contractor->id} WHERE `id` = '{$stock->id}';";
			$db->setQuery($query);
			$db->query();

			// Уж теперь все должно быть отлично - возвращаем результат
			return $stock->id;
		}
	}

	// Создает склад
	private function addStock($alias) {
	$this->addMsg("private function addStock($alias)");

		// Инициализируем переменные и готовим запрос
		$db =& JFactory::getDBO();

		// Выполняем запрос
		$query = "
			INSERT INTO #__pricer_stock (
				`id`,
				`title`,
				`alias`,
				`contractor_id`,
				`created`)
			VALUES (
				0,
				'{$this->contractor->title} ({$alias})',
				'{$alias}',
				'{$this->contractor->id}',
				NOW()
			);
		";
		$db->setQuery($query);
		$db->query();
	}

	// Возвращает id типа цены (по alias из базы), если его нет - добавляет
	private function getPriceType($alias) {
	$this->addMsg("private function getPriceType($alias)");

		// Инициализируем переменные
		$db =& JFactory::getDBO();

		// Выполняем запрос
		$query = "SELECT * FROM `#__pricer_price_type` WHERE `alias` = '{$alias}';";
		$db->setQuery($query);
		$priceType = $db->loadObject();

		// Проверяем существование типа цены
		if (true == $priceType->id) { // Тип цены есть

			// Возвращаем результат
			return $priceType->id;

		} else { // Типа цены нет

			// Добавляем тип цены в базу
			$this->addPriceType($alias);

			// Повторно выполняем запрос
			$query = "SELECT * FROM `#__pricer_price_type` WHERE `alias` = '{$alias}';";
			$db->setQuery($query);
			$priceType = $db->loadObject();

			// Возвращаем результат
			return $priceType->id;
		}
	}

	// Создает склад
	private function addPriceType($alias) {
	$this->addMsg("private function addPriceType($alias)");

		// Инициализируем переменные и готовим запрос
		$db =& JFactory::getDBO();

		// Выполняем запрос
		$query = "
			INSERT INTO #__pricer_price_type (
				`id`,
				`title`,
				`alias`,
				`created`)
			VALUES (
				0,
				'{$alias}',
				'{$alias}',
				NOW()
			);
		";
		$db->setQuery($query);
		$db->query();
	}

	// Загружает прайс во временную папку и возвращает ее имя
	private function getFile() {
	$this->addMsg("private function getFile()");
	JFile::delete(DS.'tmp'.DS.$this->alias.'Page.html'); // TODO удалить



		// Инициализируем переменные
		$file = DS.'tmp'.DS.$this->alias.'Data.xml';

		// Инициализируем cURL и получаем начальные куки
		if (true == $ch = curl_init()) {

			// Устанавливаем URL запроса
			curl_setopt($ch, CURLOPT_URL, 'https://b2b.ocs.ru/login.aspx');

			// Пробуем получить вывод в файл
			$fp = fopen(DS.'tmp'.DS.$this->alias.'Page.html', "w");
			curl_setopt($ch, CURLOPT_FILE, $fp);

			// Отключаем проверку сертификатов
			curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
			curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

			// Выключаем вывод заголовков
			curl_setopt($ch, CURLOPT_HEADER, false);

			// Включаем куки
			curl_setopt($ch, CURLOPT_COOKIEFILE, DS.'tmp'.DS.$this->alias.'Cookie.txt');
			curl_setopt($ch, CURLOPT_COOKIEJAR, DS.'tmp'.DS.$this->alias.'Cookie.txt');

			// Указываем максимальное время ожидания в секундах
			curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 180);

			// Устанавливаем значение поля User-agent
			curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1');

			// Выполняем запрос
			curl_exec($ch);

			// Освобождаем ресурс
			curl_close($ch);
			fclose($fp);
			unset($ch);

		}



		// Инициализируем cURL и логинимся
		if (false) { //(true == $ch = curl_init()) {

			// Устанавливаем URL запроса
			curl_setopt($ch, CURLOPT_URL, 'https://b2b.ocs.ru/login.aspx');

			// Пробуем получить вывод в файл
			$fp = fopen(DS.'tmp'.DS.$this->alias.'Page.html', "w");
			curl_setopt($ch, CURLOPT_FILE, $fp);

			// Отключаем проверку сертификатов
			curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
			curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

			// При значении true CURL включает в вывод заголовки.
			curl_setopt($ch, CURLOPT_HEADER, false);

			// Включаем куки
			curl_setopt($ch, CURLOPT_COOKIEJAR, DS.'tmp'.DS.$this->alias.'Cookie.txt');

			// Указываем, что будет POST запрос
			curl_setopt($ch, CURLOPT_POST, true);

			//	Передаем значения переменных
			//__LASTFOCUS=
//				&__EVENTTARGET=
//				&__EVENTARGUMENT=
//				&__VIEWSTATE=%2FwEPDwULLTE1MTMzNDc2MjdkGAEFHl9fQ29udHJvbHNSZXF1aXJlUG9zdEJhY2tLZXlfXxYBBRpjdGwwMCRDb250ZW50JGNiUmVtZW1iZXJNZQ%3D%3D
//				&ctl00%24Content%24txtUsername={$this->updater->login}
//				&ctl00%24Content%24txtPassword={$this->updater->pass}
//				&ctl00%24Content%24cbRememberMe=on
//				&ctl00%24Content%24btnLogin=%D0%92%D0%BE%D0%B9%D1%82%D0%B8
//				&ctl00%24Content%24hdnPassword=
//				&ctl00%24Content%24hdnLogin=
//				&ctl00%24Content%24hdnStep=
			curl_setopt($ch, CURLOPT_POSTFIELDS, "__LASTFOCUS=&__EVENTTARGET=&__EVENTARGUMENT=&__VIEWSTATE=%2FwEPDwULLTE1MTMzNDc2MjdkGAEFHl9fQ29udHJvbHNSZXF1aXJlUG9zdEJhY2tLZXlfXxYBBRpjdGwwMCRDb250ZW50JGNiUmVtZW1iZXJNZQ%3D%3D&ctl00%24Content%24txtUsername={$this->updater->login}&ctl00%24Content%24txtPassword={$this->updater->pass}&ctl00%24Content%24cbRememberMe=on&ctl00%24Content%24btnLogin=%D0%92%D0%BE%D0%B9%D1%82%D0%B8&ctl00%24Content%24hdnPassword=&ctl00%24Content%24hdnLogin=&ctl00%24Content%24hdnStep=");

			// Указываем максимальное время ожидания в секундах
			curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 180);

			// Устанавливаем значение поля User-agent
			curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1');

			// Выполняем запрос
			curl_exec($ch);

			// Освобождаем ресурс
			curl_close($ch);
			fclose($fp);
			unset($ch);
//			JFile::delete(DS.'tmp'.DS.$this->alias.'Page.html');
		} else {
			return false;
		}

		// Инициализируем cURL и загружаем прайс
		if (false) { // (true == $ch = curl_init()) {

			// Устанавливаем URL запроса
			curl_setopt($ch, CURLOPT_URL, 'https://b2b.treolan.ru/catalog.excel.asp?category=04030AB1-678B-457D-8976-AC7297C65CE6&vendor=0&ncfltr=1&daysback=0&reporttype=stock&price_min=&price_max=&hdn_extParams=&tvh=0&srh=&sart=on');

			// Пробуем получить вывод в файл
			$fp = fopen($file, "w");
			curl_setopt($ch, CURLOPT_FILE, $fp);

			// Отключаем проверку сертификатов
			curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
			curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

			// Выключаем вывод заголовков
			curl_setopt($ch, CURLOPT_HEADER, false);

			// Включаем куки
			curl_setopt($ch, CURLOPT_COOKIEFILE, DS.'tmp'.DS.$this->alias.'Cookie.txt');
			curl_setopt($ch, CURLOPT_COOKIEJAR, DS.'tmp'.DS.$this->alias.'Cookie.txt');

			// Указываем максимальное время ожидания в секундах
			curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 180);

			// Устанавливаем значение поля User-agent
			curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1');

			// Выполняем запрос
			curl_exec($ch);

			// Освобождаем ресурс
			curl_close($ch);
			fclose($fp);
			unset($ch);
			JFile::delete(DS.'tmp'.DS.$this->alias.'Cookie.txt');
		} else {
			return false;
		}
		return $file;
	}

	// Возвращает массив данных
	private function getData($file) {
	$this->addMsg("private function getData($file)");

		// Загружаем данные из файла в DOM
		$dom = new DomDocument();
		$dom->loadHtmlFile($file);
		$xpath = new DOMXPath($dom);

		// Парсим и загружаем в массив
		$row = 0;
		foreach ($xpath->query('.//tr') as $tr) {
			$col = 0;
			foreach ($tr->childNodes as $td) {
				$this->data[$row][$col] = $td->nodeValue;
				$col++;
			}
			$row++;
		}
		return true;
	}

	// Идентифицирует колонки
	private function getNumbers() {
	
		for ($col=0; $col<sizeof($this->data[0]); $col++) {
			switch ($this->data[0][$col]) {
				case 'Производитель' : $this->number['vendor']        = $col; break;
				case 'Артикул'       : $this->number['article']       = $col; break;	
				case 'Наименование'  : $this->number['name']          = $col; break;
				case 'Цена*'         : $this->number['price_USD']     = $col; break;
				case 'Цена руб.**'   : $this->number['price_RUB']     = $col; break;
				case 'Св.'           : $this->number['stock_russia']  = $col; break;
				case 'Св.+Тр.'       : $this->number['stock_transit'] = $col; break;
				case 'Доп.'          : $this->number['comment']       = $col; break;
				case 'Гар.'          : $this->number['warranty']      = $col; break;
				case 'Вес [кг.]'     : $this->number['mass']          = $col; break;
				case 'Объем [литры]' : $this->number['volume']        = $col; break;
			}
		}
		if (0 === $this->number['article'] and $this->number['vendor'] and $this->number['name'] and $this->number['price_USD'] and $this->number['price_RUB'] and $this->number['stock_russia'] and $this->number['stock_transit'] and $this->number['comment'] and $this->number['warranty']) { // Все колонки на месте
			return true;
		} else { // Не хватает обязательных колонок
			$this->addMsg('Формат прайс-листа поменялся - необходима доработка обработчика.');
			return false;
		}
	}

	// Снятие с публикации устаревшей информации о ценах и количествах товара на складах
	private function clearSQL() {

		// Инициализация переменных
		$db =& JFactory::getDBO();

		// Чистка цен
		$query = "UPDATE `#__pricer_price` SET state = '0' WHERE `contractor_id` = '{$this->contractor->id}';";
		$db->setQuery($query);
		$db->query();

		// Чистка склада
		$query = "UPDATE `#__pricer_product_quantity` SET state = '0' WHERE `stock_id` = '{$this->stock['treolan-russia-stock']}';";
		$db->setQuery($query);
		$db->query();

		// Чистка транзита
		$query = "UPDATE `#__pricer_product_quantity` SET state = '0' WHERE `stock_id` = '{$this->stock['treolan-russia-transit']}';";
		$db->setQuery($query);
		$db->query();

		// Возвращаем результат
		return true;
	}

	// Заносит информацию в базу
	private function toSQL() {

		// Цикл по всем строкам
		for ($row=1; $row<sizeof($this->data); $row++) {
			if (1 == sizeof($this->data[$row])) { // Строка с категорией

				// Получаем id категории
				$categoryId = $this->getCategoryId($this->data[$row][0]);
				continue;
			} elseif (true == $this->data[$row][$this->number['article']] and $this->data[$row][$this->number['vendor']]) { // Товар

				// Получаем id производителя
				$vendorId = $this->getVendorId($this->data[$row][$this->number['vendor']]);

				// Проверяем, указаны ли id производителя и категории
				if ((true == $categoryId) and (true == $vendorId)) {
					$productId = $this->getProductId($vendorId, $categoryId, $this->data[$row]);
				} else {
					continue;
				}
				
				// Проверяем, указаны ли id продукта и его долларовая цена
				$price = $this->getPrice($this->data[$row][$this->number['price_USD']]);
				if ((true == $productId) and (true == $price)) { // Добавляем цену
					$this->addPrice($productId, $this->contractor->id, $price, 'USD');
				}

				// Проверяем, указаны ли id продукта и его рублевая цена
				$price = $this->getPrice($this->data[$row][$this->number['price_RUB']]);
				if ((true == $productId) and (true == $price)) { // Добавляем цену
					$this->addPrice($productId, $this->contractor->id, $price, 'RUB');
				}

				// Проверяем, указаны ли id продукта и его количество
				$quantity = $this->getQuantity($this->data[$row][$this->number['stock_russia']]);
				if ((true == $productId) and (true == $quantity)) { // Добавляем информацию о количестве
					$this->addQuantity($productId, $this->stock['treolan-russia-stock'], $quantity);
				}

				// Проверяем, указаны ли id продукта и его количество
				$quantity = $this->getQuantity($this->data[$row][$this->number['stock_transit']]);
				if ((true == $productId) and (true == $quantity)) { // Добавляем информацию о количестве
					$this->addQuantity($productId, $this->stock['treolan-russia-transit'], $quantity);
				}
			}
		}
		return true;
	}

	// Определяем id категории
	private function getCategoryId($categorySynonym) {

		// Инициализируем переменные
		$db =& JFactory::getDBO();

		// Выполняем запрос
		$query = "SELECT `id`, `catid`, `title` FROM `#__pricer_category_synonym` WHERE '{$categorySynonym}' <=> `title`;";
		$db->setQuery($query);
		$category = $db->loadObject();

		// Проверяем
		if (true == $category->catid) { // Есть синоним категории и к нему присвоена категория
			return $category->catid;;
		} elseif (false == $category->id) { // Нет синонима категории в базе - добавляем его
			$this->addCategorySynonym($categorySynonym);
			return false;
		} else { // Есть синоним категории, но категория к нему не привязана
			return false;
		}
	}

	// Добавляет синоним категории в базу
	private function addCategorySynonym($categorySynonym) {

		// Инициализируем переменные
		$db =& JFactory::getDBO();

		// Добавляем синоним категории
		$query = "INSERT INTO `#__pricer_category_synonym` (`id`, `title`, `catid`, `contractor_id`, `created`)
			VALUES ('0', '{$categorySynonym}', NULL, '{$this->contractor->id}', NOW());";
		$db->setQuery($query);
		$db->query();
	}

	// Определяем id производителя
	private function getVendorId($vendorSynonym) {

		// Инициализируем переменные
		$db =& JFactory::getDBO();

		// Выполняем запрос
		$query = "SELECT `id`, `vendor_id`, `title` FROM `#__pricer_vendor_synonym` WHERE '{$vendorSynonym}' <=> `title`;";
		$db->setQuery($query);
		$vendor = $db->loadObject();

		// Проверяем
		if (true == $vendor->vendor_id) { // Есть синоним производителя и к нему присвоен производитель
			$vendorId = $vendor->vendor_id;
			return $vendorId;
		} elseif (false == $vendor->id) { // Нет синонима производителя в базе - добавляем его
			$this->addVendorSynonym($vendorSynonym);
			return false;
		} else { // Есть синоним производителя, но производитель к нему не привязан
			return false;
		}
	}

	// Добавляет синоним производителя
	private function addVendorSynonym($vendorSynonym) {

		// Инициализируем переменные
		$db =& JFactory::getDBO();

		// Добавляем синоним категории
		$query = "INSERT INTO `#__pricer_vendor_synonym` (`id`, `title`, `vendor_id`, `created`)
			VALUES ('0', '{$vendorSynonym}', NULL, NOW());";
		$db->setQuery($query);
		$db->query();
	}

	// Возвращает id продукта
	private function getProductId($vendorId, $categoryId, $product) {

		// Инициализируем переменные
		$db =& JFactory::getDBO();

		// Запрашиваем информацию о продукте из базы
		$query = '
			SELECT
				`id`,
				`article`,
				`vendor_id`,
				`title`
			FROM `#__pricer_product`
			WHERE'.' '
				.$db->Quote($vendorId).' = `vendor_id` AND'.' '
				.$db->Quote($product[$this->number['article']]).' = `article`
			;
		';
		$db->setQuery($query);
		$productFromSQL = $db->loadObject();

		// Проверяем, есть ли товар в базе
		if (true == $productFromSQL->id) { // Товар есть в базе - возвращаем его id
			return $productFromSQL->id;
		} else { // Товара нет в базе - добавляем его

			// Проверяем наличие необходимой информации о продукте
			if ((true == $vendorId) and (true == $product[$this->number['name']]) and (true == $product[$this->number['article']])) { // Есть

				// Заносим информацию в базу
				$query = '
					INSERT INTO #__pricer_product (
						`id`,
						`title`,
						`alias`,
						`catid`,
						`vendor_id`,
						`article`,
						`created`)
					VALUES (
						0, '
						.$db->Quote($product[$this->number['name']]).', '
						.$db->Quote($product[$this->number['name']]).', '
						.$db->Quote($categoryId).', '
						.$db->Quote($vendorId).', '
						.$db->Quote($product[$this->number['article']]).', '
						.'NOW()
					);
				';
				$db->setQuery($query);
				$db->query();

				// Повторно запрашиваем
				$query = '
					SELECT
						`id`,
						`article`,
						`vendor_id`,
						`title`
					FROM `#__pricer_product`
					WHERE'.' '
						.$db->Quote($vendorId).' = `vendor_id` AND'.' '
						.$db->Quote($product[$this->number['article']]).' = `article`
					;
				';
				$productFromSQL = $db->loadObject();

				// Проверяем, появился ли товар в базе
				if (true == $productFromSQL->id) { // Товар есть в базе - возвращаем его id
					$this->addMsg("\$vendorId = {$vendorId}, \$product['article'] = {$product[$this->number['article']]} - успешно добавлен");
					return $productFromSQL->id;
				} else { // Товара нет в базе - не удалось добавить
					$this->addMsg("Ошибка при добавлении: \$vendorId = {$vendorId}, \$product['article'] = {$product[$this->number['article']]}.");
					return false;
				}
			} else { // Недостаточно информации о товаре
				$this->addMsg("// Недостаточно информации о товаре");
				return false;
			}
		}
	}

	// Правим цену (удаляем вредные символы)
	private function getPrice($price) {
		$price = ereg_replace('[,]', '.', $price);
		$price = ereg_replace('[ ]', '', $price);
		return doubleval($price);
	}

	// Заносим цену в базу
	private function addPrice($productId, $contractorId, $price, $currencyAlias) {

		// Инициализируем переменные
		$db =& JFactory::getDBO();

		// Заносим информацию в базу
		$query="
			INSERT INTO `#__pricer_price` (
				`contractor_id`,
				`product_id`,
				`created`,
				`price`,
				`currency_alias`,
				`price_type_id`,
				`publish_up`,
				`publish_down`)
			VALUES (
				'{$contractorId}',
				'{$productId}',
				NOW(),
				'{$price}',
				'$currencyAlias',
				'{$this->priceType['rdp']}',
				NOW(),
				ADDDATE(NOW(),3)
			);
		";
		$db->setQuery($query);
		$db->query();
		return true;
	}

	// Правим количество (удаляем вредные символы)
	private function getQuantity($string) {
		$int = ereg_replace('[^0-9]*', '', $string); // убираем из строки все, что не цифра
		if (true == $int) {
			return $int;
		} else {
			$string = utf8_strtolower($string);
			switch ($string) {
				case '0' : return 0; // В противном случае нули выбывают из обработки
				case 'склад' : return 1;
				case 'резерв' : return 0;
				case 'транзит' : return 1;
				case 'много' : return 10;
				case 'мало' : return 5;
				default : $this->addMsg ("Необходим новый кейс обработки количества: '$string'"); return 0;
			}
		}
	}

	// Заносим количество в базу
	private function addQuantity($productId, $stockId, $quantity) {

		// Инициализируем переменные
		$db =& JFactory::getDBO();

		// Заносим информацию в базу
		$query="
			INSERT INTO `#__pricer_product_quantity` (
				`product_id`,
				`stock_id`,
				`created`,
				`quantity`,
				`publish_up`,
				`publish_down`)
			VALUES (
				'{$productId}',
				'{$stockId}',
				NOW(),
				'{$quantity}',
				NOW(),
				ADDDATE(now(), 3)
			);
		";
		$db->setQuery($query);
		$db->query();
		return true;
	}

	// Возвращает строку сообщений
	public function getMsg() {
		return $this->msg;
	}

	// Добавляет сообщение
	private function addMsg($msg) {
		$this->msg .= "{$msg}<br/>\n";
	}
}
/*
	// Возвращает сегодняшнюю дату в формате 2012-12-21
	protected function getDate() {

		// Определяем дату
		$date = getdate();

		// Правим день и месяц
		if ($date['mon'] < 10) {
			$date['mon'] = '0'.$date['mon'];
		}
		if ($date['mday'] < 10) {
			$date['mday'] = '0'.$date['mday'];
		}

		// Формируем дату и возвращаем результат
		$date = "{$date['year']}-{$date['mon']}-{$date['mday']}";
		return $date;
	}

	// Возвращает адрес, по которому доступно обновление
	protected function getURL() {

		// Определяем дату
		$date = getdate();

		// Правим день и месяц
		if ($date['mon'] < 10) {
			$date['mon'] = '0'.$date['mon'];
		}
		if ($date['mday'] < 10) {
			$date['mday'] = '0'.$date['mday'];
		}

		// Формируем URL и возвращаем результат
		$url = "http://cbr.ru/eng/currency_base/D_print.aspx?date_req={$date['mday']}.{$date['mon']}.{$date['year']}";
		return $url;
	}

	// Возвращает массив данных
	protected function getData() {
		$dom = new DomDocument();
		$dom->loadHtmlFile($this->url);
		$row = 0;
		$xpath = new DOMXPath($dom);
		foreach ($xpath->query('//table[@class = "CBRTBL"]/tr') as $tr) {
			$col = 0;
			foreach ($tr->childNodes as $td) {
				$data[$row][$col] = $td->nodeValue;
//				$this->addMsg("\$data[{$row}][{$col}] = {$data[$row][$col]}");
				$col++;
			}
			$row++;
		}
		return $data;
	}

	// Возвращает массив номеров колонок
	protected function getNumbers() {
		for ($col=0; $col<sizeof($this->data[0]); $col++) {
			switch ($this->data[0][$col]) {
				case 'Num Ñode'  : $numbers['code']	  = $col+0; break;
				case 'Char Ñode' : $numbers['alias']    = $col+1; break;
				case 'Unit'        : $numbers['quantity'] = $col+2; break;
				case 'Currency'    : $numbers['name']     = $col+3; break;
				case 'Rate'        : $numbers['rate']     = $col+4; break;
			}
		}
//		$this->addMsg("{$numbers['code']} = \$numbers['code']");
//		$this->addMsg("{$numbers['alias']} = \$numbers['alias']");
//		$this->addMsg("{$numbers['quantity']} = \$numbers['quantity']");
//		$this->addMsg("{$numbers['name']} = \$numbers['name']");
//		$this->addMsg("{$numbers['rate']} = \$numbers['rate']");
		if ((0 === $numbers['code'])
			and (2 == $numbers['alias'])
			and (4 == $numbers['quantity'])
			and (6 == $numbers['name'])
			and (8 == $numbers['rate'])) {
			return $numbers;
		} else {
			$this->addMsg('Формат выгрузки курсов валют изменился - необходима доработка парсера.');
			return false;
		}
	}

	// Загружает информацию в базу банных
	protected function onParsing() {
	
		// Подключаемся к базе
		$db =& JFactory::getDBO();

		// Цикл по всем строкам
		for ($row=1; $row<sizeof($this->data); $row++) {

			// Определяем переменные
			$code = $this->getCode($row);
			$quantity = $this->getQuantity($row);
			$name = $this->getName($row);
			$alias = $this->getAlias($row, $name);
			$rate = $this->getRate($row);
			// Проверяем, есть ли курс на текущую дату
			$query = "
				SELECT rate
				FROM #__pricer_currency_rate
				WHERE
					#__pricer_currency_rate.currency_alias = '{$alias}' AND
					#__pricer_currency_rate.date = '{$this->date}';
			";
//			$this->addMsg($query);
			$db->setQuery($query);
			$rateOnSQL = $db->loadResult();
			if (true == $rateOnSQL) { // Курс валюты на текущее число уже есть
				$this->addMsg("Курс валюты {$alias} на текущую дату уже есть.");
			} else { // Курс валюты на текущее число отсутствует
				// Помечаем устаревшие курсы
				$this->setZeroState($alias);
				// Заносим информацию в базу
				$query = "INSERT INTO #__pricer_currency_rate (`currency_alias`, `date`, `rate`, `quantity`, `state`, `created`, `created_by`, `modified`, `modified_by`) VALUES ('{$alias}', '{$this->date}', '{$rate}', '{$quantity}', '1', NOW(), '1', NOW(), '1');";
				$db->setQuery($query);
				$db->query();
			}
		}
		return true;
	}

	protected function getCode($row) {
		$code = $this->data[$row][$this->numbers['code']];
		return $code;
	}

	protected function getQuantity($row) {
		$quantity = $this->data[$row][$this->numbers['quantity']];
		return $quantity;
	}

	protected function getName($row) {
		$name = $this->data[$row][$this->numbers['name']];
		return $name;
	}

	// Выполнять только после определения имени
	protected function getAlias($row, $name) {

		// Подключаемся к базе
		$db =& JFactory::getDBO();

		// Получаем значение и чистим его от мусора
		$alias = $this->data[$row][$this->numbers['alias']];
		$alias = $this->clearAlias($alias);

		// Проверяем по буквенному коду - есть ли валюта в базе
		$query = "SELECT id FROM #__pricer_currency WHERE '{$alias}' <=> #__pricer_currency.alias;";
		$db->setQuery($query);
		$id = $db->loadResult();
		if (true == $id) { // Есть такая валюта, возвращаем буквеный код
			return $alias;
		} else { // Нет такой валюты, добавляем
			$query = "INSERT INTO #__pricer_currency (`id`, `title`, `alias`, `name_html`, `state`, `description`, `created`, `created_by`, `modified`, `modified_by`) VALUES (0, '{$name}', '{$alias}', '{$alias}', '1', '', NOW(), '0', NOW(), '0');";
//			$this->addMsg($query);
			$db->setQuery($query);
			$db->query();

//			// Проверяем наличие после добавления
			$query = "SELECT id FROM #__pricer_currency WHERE '{$alias}' <=> #__pricer_currency.alias;";
			$db->setQuery($query);
			$id = $db->loadResult();
			if (true == $id) { // Есть такая валюта, возвращаем код
				$this->addMsg("Добавлена валюта {$alias}.");
				return $alias;
			} else { // Нет такой валюты, фиксируем ошибку при добавлении
				$this->addMsg("Добавить валюту {$alias} не удалось.");
				return false;
			}
		}
	}

	// Чистит буквенный код валюты
	protected function clearAlias($alias) {
		$alias = ereg_replace('[^A-Z]*', '', $alias);
		if (3 == strlen($alias)) {
			return $alias;
		} else {
			return false;
		}
	}

	protected function getRate($row) {
		$rate = $this->data[$row][$this->numbers['rate']];
		$rate = $this->clearRate($rate);
		return $rate;
	}

	// Снятие с публикации устаревших курсов валют
	protected function setZeroState($alias) {
		$db =& JFactory::getDBO();
		$query = "UPDATE `#__pricer_currency_rate` SET state = '0' WHERE `currency_alias` = '{$alias}';";
		// $this->addMsg($query);
		$db->setQuery($query);
		$db->query();
		return true;
	}


	// Преобразует курс в удобоваримый для базы вид
	protected function clearRate($string) {
		$string = ereg_replace('[,]', '.', $string);
		$string = ereg_replace('[ ]', '', $string);
		return doubleval($string);
	}

	// Преобразует количество из строки в число
	protected function clearQuantity($string) {
		$int = ereg_replace('[^0-9]*', '', $string); // убираем из строки все, что не цифра
		if (true == $int) {
			return $int;
		} else {
			$string = utf8_strtolower($string);
			switch ($string) {
				case '0': return 0; // В противном случае нули выбывают из обработки
				default : $this->msg .= 'Необходим новый кейс обработки количества: ['.$string."].\n"; return 0;
			}
		}
	}

	// Отмечает время загрузки
	protected function setUpdated() {
		$db =& JFactory::getDBO();
		$query = "UPDATE `#__pricer_robot` SET `updated` = NOW() WHERE `id` = '{$this->updater->id}';";
		$db->setQuery($query);
		$db->query();
		return true;
	}

	// Возвращает строку сообщений
	public function getMsg() {
		return $this->msg;
	}

	// Добавляет сообщение
	protected function addMsg($msg) {
		$this->msg .= "{$msg}<br/>\n";
	}
}*/
